package messages

// MessageType represents different types of messages
type MessageType string

const (
	// Message types
	TypeRequirement    MessageType = "requirement"
	TypeDesign         MessageType = "design"
	TypeCode           MessageType = "code"
	TypeUserStory      MessageType = "user_story"
	TypeArchitecture   MessageType = "architecture"
	TypeResponse       MessageType = "response"
	TypeRequest        MessageType = "request"
	TypeError          MessageType = "error"
	TypePrediction     MessageType = "prediction"
	TypeStream         MessageType = "stream"
	TypeDirect         MessageType = "direct"
	TypeBroadcast      MessageType = "broadcast"
	TypeCollaboration  MessageType = "collaboration"
	TypeKnowledgeShare MessageType = "knowledge_share"
	TypeTeamSync       MessageType = "team_sync"
)

// Message represents a message in the system
type Message interface {
	GetContent() string
	GetRole() string
	GetType() MessageType
	GetAction() string
}

// BaseMessage represents a basic message implementation
type BaseMessage struct {
	ID        string                 `json:"id"`
	Type      MessageType            `json:"type"`
	Content   string                 `json:"content"`
	Metadata  map[string]interface{} `json:"metadata"`
	Timestamp int64                  `json:"timestamp"`
}

// BasicMessage represents a basic message implementation
type BasicMessage struct {
	MessageID   string
	MsgType     MessageType
	MsgContent  string
	MsgMetadata map[string]interface{}
}

// PID represents a process ID
type PID interface {
	Address() string
	ID() string
}

// Implement Message interface for BaseMessage
func (m *BaseMessage) GetID() string                       { return m.ID }
func (m *BaseMessage) GetType() MessageType                { return m.Type }
func (m *BaseMessage) GetContent() string                  { return m.Content }
func (m *BaseMessage) GetMetadata() map[string]interface{} { return m.Metadata }
func (m *BaseMessage) GetTimestamp() int64                 { return m.Timestamp }
func (m *BaseMessage) String() string                      { return m.Content }
func (m *BaseMessage) GetRole() string                     { return m.Metadata["role"].(string) }

// Implement Message interface for BasicMessage
func (m *BasicMessage) GetID() string        { return m.MessageID }
func (m *BasicMessage) GetType() MessageType { return m.MsgType }
func (m *BasicMessage) GetContent() string   { return m.MsgContent }
func (m *BasicMessage) GetMetadata() map[string]interface{} {
	return m.MsgMetadata
}
func (m *BasicMessage) GetTimestamp() int64 { return 0 }
func (m *BasicMessage) String() string      { return m.MsgContent }
func (m *BasicMessage) GetRole() string     { return m.MsgMetadata["role"].(string) }
func (m *BasicMessage) GetAction() string   { return "" }

// NewMessage creates a new message with the given role and content
func NewMessage(role, content string, msgType MessageType) Message {
	return &BasicMessage{
		MsgType:     msgType,
		MsgContent:  content,
		MsgMetadata: map[string]interface{}{"role": role},
	}
}

// NewBasicMessage creates a new basic message
func NewBasicMessage(msgType MessageType, content string) Message {
	return &BasicMessage{
		MsgType:     msgType,
		MsgContent:  content,
		MsgMetadata: map[string]interface{}{"role": "system"},
	}
}
